'''
@Company: TWL
@Author: xue jian
@Email: xuejian@kanzhun.com
@Date: 2020-07-20 16:14:28
'''
import os
import sys
import json
sys.path.append(os.path.abspath(os.path.join(os.path.dirname('__file__'), os.path.pardir)))

import thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from hulk_proxy.HulkProxyServ import Client
from scan_data.ttypes import ScanData
import random
import time
from cityhash import CityHash64


HOST = "172.21.32.54"
PORT = 10088
import time
def log(msg):
    print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())+" | "+msg)

def string2fid(value, slot):
    return CityHash64(str(value)) & ((1<<52) -1) | (slot << 52)

class Transfer:
    def __init__(self):

        try:
            tsocket = TSocket.TSocket(HOST, PORT)
            transport = TTransport.TFramedTransport(tsocket)
            protocol = TBinaryProtocol.TBinaryProtocol(transport)
            client = Client(protocol)

            transport.open()
            
            # ==========gen the fea_code, where k is fea_name, v is fea_code================
            fea_code_file = client.hget('feature_meta', 'fea_code_map')
            self.fea_code = json.loads(fea_code_file)
            
            # del_keys = []
            # new_keys = []
            # codes = []
            for k,v in self.fea_code.items():
                self.fea_code[k] = str(v['code'])

            fea_code_tmp = client.hget('feature_meta', 'feature_code')
            fea_code_tmp = json.loads(fea_code_tmp)
            for k, v in fea_code_tmp['geek_features'].items():
                self.fea_code[v] = k
            for k, v in fea_code_tmp['boss_features'].items():
                self.fea_code[v] = k
            for k, v in fea_code_tmp['crossing_features'].items():
                self.fea_code[v] = k

            #     if k == 'expect_position':
            #         del_keys.append(k)
            #         new_keys.append('geek_position')
            #         codes.append(str(v['code']))
            #     elif k == 'expect_city':
            #         del_keys.append(k)
            #         new_keys.append('geek_city')
            #         codes.append(str(v['code']))
            #     elif k == 'job_position':
            #         del_keys.append(k)
            #         new_keys.append('boss_position')
            #         codes.append(str(v['code']))
            #     elif k == 'job_city':
            #         del_keys.append(k)
            #         new_keys.append('boss_city')
            #         codes.append(str(v['code']))
            #     elif k == 'b2g_w2v_int_orig_gof':
            #         del_keys.append(k)
            #         new_keys.append('b2g_w2v_orig_gof')
            #         codes.append(str(v['code']))
            #     elif k == 'b2g_w2v_pref_gof_new':
            #         del_keys.append(k)
            #         new_keys.append('b2g_w2v_pref_gof')
            #         codes.append(str(v['code']))
            #     else:
            #         self.fea_code[k] = str(v['code'])
            # for i, v in enumerate(del_keys):
            #     self.fea_code[new_keys[i]] = codes[i]
            #     del(self.fea_code[v])
            # print(self.fea_code)
            # ===============================================================
            
            # ==========gen fea_slot, k is fea_name and v is the slot========
            fea_slot_str = client.hget('feature_meta', 'feature_slot')
            self.fea_slot = json.loads(fea_slot_str)
            # for k, v in self.fea_slot.items():
            #     self.fea_slot[k] = v['slot']
            # print(self.fea_slot)

            # =====gen fea_cut, key is fea_name and v is the cut points======
            cut_points_str = client.hget('feature_meta', 'cut_points')
            cut_points = json.loads(cut_points_str)
            self.fea_cut = {}
            for k, v in self.fea_slot.items():
                slot = v['slot']
                if str(slot) in cut_points:
                    self.fea_cut[k] = cut_points[str(slot)]
            # print(self.fea_cut)

            self.rcd_source_dict = {'f1_grcd': '0', 'lat_grcd': '1', 'f2_grcd_new': '2', 'f2_grcd_seeme': '3', 'f2_grcd_interesting': '4', 'grcd_search': '5'}

            transport.close()
        except thrift.Thrift.TException as ex:
            print(ex.message)


    

    # ================the comman transfer logistic========================
    def transfer_data(self, train_data, data):
        fids = []
        fids.append(string2fid(data.get('geekId', ''), self.fea_slot['geek_id']['slot']))
        fids.append(string2fid(data.get('jobId', ''), self.fea_slot['job_id']['slot']))
        fids.append(string2fid(data.get('expectId', ''), self.fea_slot['exp_id']['slot']))
        fids.append(string2fid(data.get('bossId', ''), self.fea_slot['boss_id']['slot']))

        time_step = data.get('ts', 0)/1000
        train_data['ts'] =  time_step
        timeArray = time.localtime(time_step)
        fids.append(string2fid(time.strftime("%H", timeArray), self.fea_slot['hour_of_day']['slot']))
        day_of_week = int(time.strftime("%w", timeArray))  
        fids.append(string2fid(day_of_week, self.fea_slot['day_of_week']['slot']))

        # fids.append(string2fid(self.rcd_source_dict[data.get('rcdBzType', 'f1_grcd')], self.fea_slot['rcd_list_source']))
        fea1 = data.get('listFeatures', {})
        fea2 = data.get('userFeatures', {})
        fea1.update(fea2)
        seq_num = 0
        seq_fea = []

        
        # ================deal the word weight feature========================
        def deal_weight_fea(weight_fea):
            import heapq
            weight_fea = weight_fea.split(',')
            store = []
            for wf in weight_fea:
                wf = wf.split(':')
                store.append((float(wf[1]), wf[0]))
            return heapq.nlargest(3, store)

                

        for fea, v in self.fea_slot.items():
            slot = v['slot']
            method = v['method']
            if fea in ['geek_id', 'job_id', 'exp_id', 'boss_id', 'hour_of_day', 'day_of_week', 'rcd_list_source'] or fea not in self.fea_code:
                continue
            elif fea == 'geek_rev_work_year':
                tmp_fea = fea1.get(self.fea_code[fea], "0")
                tmp_fea = tmp_fea.split(':')[0]
                fids.append(string2fid(tmp_fea, slot))
            elif fea == 'exp_word_weight' or fea == 'job_word_weight':
                deal_fea = fea1.get(self.fea_code[fea], '-3:0.9,-3:0.8,-3:0.7')
                print(deal_fea)
                tmp = []
                try: 
                    tmp.extend(deal_weight_fea(deal_fea))
                except IndexError as e:
                    pass
                use_tmp = []
                for v in tmp:
                    use_tmp.append(v[1])
                while len(use_tmp)<3:
                    use_tmp.append('-3')
                print(use_tmp)
                for v in use_tmp:
                    fids.append(string2fid(v, slot))
            elif method == 'longarray2fid':
                
                seq_num += 1
                seq_fea.append(fea)
                tmp_fea = fea1.get(self.fea_code[fea], "-3")
                tmp_fea = tmp_fea.replace('[', '').replace(']', '')
                tmp_fea = tmp_fea.split(',')
                if len(tmp_fea) > 10:
                    tmp_fea = tmp_fea[:10]
                elif len(tmp_fea) < 10:
                    while len(tmp_fea) != 10:
                        tmp_fea.append('-3')
                for tmp_value in tmp_fea:
                        fids.append(string2fid(tmp_value, slot))  
            elif method == 'float2fid': 
                tmp_cut = self.fea_cut[fea]
                tmp_fea = float(fea1.get(self.fea_code[fea], "0"))
                tmp_res = 0
                for i in range(len(tmp_cut) - 1):
                    if tmp_fea > tmp_cut[i] and tmp_fea <= tmp_cut[i+1]:
                        tmp_res = i + 1
                if tmp_fea > tmp_cut[-1]:
                    tmp_res = len(tmp_cut) + 1
                fids.append(string2fid(tmp_res, slot)) 
            else:
                fids.append(string2fid(fea1.get(self.fea_code[fea], "0"), slot))
                # if fea == 'boss_position':
                #     print(fea, slot, string2fid(fea1.get(self.fea_code[fea], "0"), slot)>>52)
                    # sys.exit(1)
            
        train_data['fids'] = fids


    # ==============for the geek chat flow========================
    def transfer_c_data(self, data):
        # data = json.loads(data.decode())
        for fea in ['geekId', 'bossId', 'jobId', 'expectId']:
            if data.get(fea, 0) == 0:
                return None
        if data.get('label', {}).get('addf', 0) == 0:
            if random.randint(1, 15) != 5:
                return None
        train_data = {'labels': []}
        
        train_data['labels'].append(float(data.get('label', {}).get('detail', 0)))
        train_data['labels'].append(float(data.get('label', {}).get('addf', 0)))

        self.transfer_data(train_data, data)

        return json.dumps(train_data)


        
    # ==============for the boss chat flow========================
    def transfer_b_data(self, data):
        # data = json.loads(data.decode())
        for fea in ['geekId', 'bossId', 'jobId', 'expectId']:
            if data.get(fea, 0) == 0:
                return None
        train_data = {'labels': []}

        train_data['labels'].append(float(data.get('label', {}).get('detail', 0)))
        train_data['labels'].append(float(data.get('label', {}).get('addf', 0)))

        self.transfer_data(train_data, data)
        
        return json.dumps(train_data)


if __name__ == "__main__":
    transfer = Transfer()